home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)genutils.c 1.11 1/20/89
- */
- #include "assert.h"
- #include "addresses.h"
- #include "nodes.h"
- #include "map.h"
- #include "sequence.h"
- #include "system.h"
- #include "builtins.h"
- #include "evaluate.h"
- #include "opNames.h"
- #include "primitives.h"
- #include "allocate.h"
- #include "MyParser.h"
- #include "datadesc.h"
- #include "environment.h"
- #include "regdefs.h"
- #include "genutils.h"
- #include "scan.h"
- #include "semantics.h"
- #include "emit.h"
- #include "trace.h"
- #include "flags.h"
- #include "option.h"
-
- /*
- * Utility routines for writing to the code file.
- */
-
- char *junk = "junk";
- #ifdef vax
- char *registerName[] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "sp", "pc", "junk"
- };
- #endif
- #ifdef sun
- char *registerName[] = {
- "a0", "a1", "d0", "d1", "a2", "a3", "d2", "d3",
- "d4", "d5", "d6", "a4", "a5", "a6", "sp", "pc", "junk"
- };
- #endif
-
- typedef struct sHSEntry {
- NodePtr p;
- int startlabel;
- int fhlabel;
- int belabel;
- int loopexitlabel;
- struct sBEntry *parent;
- struct sHSEntry *next;
- } HSEntry, *HSEntryPtr;
- static HSEntryPtr HSStackTop = NULL;
-
- typedef struct sBEntry {
- int bslabel;
- int uhlabel;
- int fhlabel;
- int belabel;
- struct sBEntry *parent;
- } BEntry, *BEntryPtr;
- static BEntryPtr BStackTop = NULL;
-
- Boolean wroteCode;
-
- static int lastLineNumber;
- IPMapCollectorPtr lineNumberMap;
- IPMapCollectorPtr unavailableHandlerMap;
- IPMapCollectorPtr failureHandlerMap;
-
- void initializeMaps()
- {
- int label = nextLabelNumber++;
-
- lastLineNumber = -1;
- wroteCode = FALSE;
- if (! doGenerateCode) {
- failureHandlerMap = createIPMap(label);
- unavailableHandlerMap = createIPMap(label);
- lineNumberMap = createIPMap(label);
- }
- BStackTop = NULL;
- emit("L_%d:\n", label);
- }
-
- void forceLineNumber()
- {
- lastLineNumber = -1;
- }
-
- void lineNumberComment(p)
- NodePtr p;
- {
- int label;
- if ((lastLineNumber == -1 || wroteCode) && lastLineNumber != p->lineNumber){
- label = nextLabelNumber++;
- emit("L_%d:\t", label);
- if (gtflag) {
- #ifdef vax
- emit("blbc\t*$ _emTracing,1f\n");
- #endif
- #ifdef sun
- emit("tstl\t_emTracing\n");
- emit("\tbeq\t1f\n");
- #endif
- emit("\tj%s\t%s_em_trace\n", JN(SUBR), GLOBALVARINDICATOR);
- emit("1:\t");
- }
- if (lastLineNumber > 0)
- addToIPMap(&lineNumberMap, label, -1, lastLineNumber);
- Comment("\t\t\t\t\"%s\", line %d", currentFileName, p->lineNumber);
- TRACE1(linenumber, 1, "Line number %d", p->lineNumber);
- }
- lastLineNumber = p->lineNumber;
- wroteCode = FALSE;
- }
-
- void finalizeMaps()
- {
- int label = nextLabelNumber++;
- emit("L_%d:\n", label);
- addToIPMap(&failureHandlerMap, label, -1, 0);
- addToIPMap(&unavailableHandlerMap, label, -1, 0);
- addToIPMap(&lineNumberMap, label, -1, lastLineNumber);
- }
-
- Boolean mapHasEntries(m)
- register IPMapCollectorPtr m;
- {
- if (m->nextToFill == 0) return(FALSE);
- if (m->nextToFill == 1 && m->entry[0].dataLabel < 0 && m->entry[0].value == 0)
- return(FALSE);
- return(TRUE);
- }
-
- void dumpMaps()
- {
- if (! doGenerateCode) return;
- if (mapHasEntries(failureHandlerMap)) {
- emit("L_failureHandlerMap:\n");
- dumpIPMap(failureHandlerMap);
- }
- if (mapHasEntries(unavailableHandlerMap)) {
- emit("L_unavailableHandlerMap:\n");
- dumpIPMap(unavailableHandlerMap);
- }
- if (mapHasEntries(lineNumberMap)) {
- emit("L_lineNumberMap:\n");
- dumpIPMap(lineNumberMap);
- }
- }
-
- extern int indexSize;
-
- char *addressToString(a)
- Address a;
- {
- static char buffer[32];
- if (a.base == Register) {
- sprintf(buffer, "%s", RN(a.offset));
- } else if (a.autoDecrement || a.autoIncrement) {
- assert(a.offset == 0);
- assert(! (a.autoDecrement && a.autoIncrement));
- #ifdef vax
- sprintf(buffer, "%s(%s)%s",
- a.autoDecrement ? "-" : "",
- RN(a.base),
- a.autoIncrement ? "+" : "");
- #endif
- #ifdef sun
- sprintf(buffer, "%s@%s", RN(a.base), a.autoDecrement ? "-" : "+");
- #endif
- } else {
- if (a.hasIndex) {
- #ifdef vax
- sprintf(buffer, "%d(%s)[%s]", a.offset, RN(a.base), RN(a.indexReg));
- #endif
- #ifdef sun
- assert(indexSize > 0);
- if (indexSize == 1) {
- sprintf(buffer, "%s@(%d,%s:l)", RN(a.base), a.offset, RN(a.indexReg));
- } else {
- sprintf(buffer, "%s@(%d,%s:l:%d)", RN(a.base), a.offset, RN(a.indexReg), indexSize);
- }
- #endif
- } else if (a.offset == 0) {
- #ifdef vax
- sprintf(buffer, "(%s)", RN(a.base));
- #endif
- #ifdef sun
- sprintf(buffer, "%s@", RN(a.base));
- #endif
- } else {
- #ifdef vax
- sprintf(buffer, "%d(%s)", a.offset, RN(a.base));
- #endif
- #ifdef sun
- sprintf(buffer, "%s@(%d)", RN(a.base), a.offset);
- #endif
- }
- }
- return(buffer);
- }
-
- DD nullDD, pusher, popper, nilDD;
- NodePtr nilNode;
- Context anyContext, pslContext, pusherContext;
-
- Boolean DDNeedsLabel(d)
- DD d;
- {
- return(d.kind == DD_OIDToODP || d.kind == DD_OIDToODAP ||
- d.kind == DD_AbCon || d.kind == DD_OIDToCodePtr);
- }
-
- #define abs(N) ((N) < 0 ? (-(N)) : (N))
-
- void writeLabel(d, c)
- DD d;
- char c;
- {
- assert(d.kind == DD_Label);
- if (d.value.label < 100) {
- emit("%d%c", abs(d.value.label),
- d.value.label < 0 ? 'b' : 'f');
- } else {
- emit("L_%d", d.value.label);
- }
- if (c != '\0') (void) emit("%c", c);
- }
-
- extern Boolean formatAs0r;
-
- void writeDD(d, c)
- DD d;
- char c;
- {
- NodePtr p;
- wroteCode = TRUE;
- switch (d.kind) {
- case DD_Label:
- #ifdef sun
- emit("pc@(");
- #endif
- if (d.value.label < 100) {
- emit("%d%c", abs(d.value.label), d.value.label < 0 ? 'b' : 'f');
- } else {
- emit("L_%d", d.value.label);
- }
- #ifdef sun
- emit("-.-2:l)");
- #endif
- break;
- case DD_Address:
- emit(addressToString(d.value.address));
- break;
- case DD_Manifest:
- if (d.value.manifest & 0xc0000000) {
- emit("%c0x%08x", IMMEDIATECHAR, d.value.manifest);
- } else {
- emit("%c%d", IMMEDIATECHAR, d.value.manifest);
- }
- break;
- case DD_RealManifest:
- #ifdef vax
- emit("%c0f%s", IMMEDIATECHAR, d.value.realmanifest);
- #endif
- #ifdef sun
- if (formatAs0r) {
- emit("%c0r%s", IMMEDIATECHAR, d.value.realmanifest);
- } else {
- float f;
- double atof();
- f = atof(d.value.realmanifest);
- emit("%c0x%08x", IMMEDIATECHAR, (* ((int *)&f)));
- }
- #endif
- break;
- case DD_PSLCondition:
- assert(FALSE);
- break;
- case DD_OIDToODP:
- emit("%c0xabcdef01", IMMEDIATECHAR);
- p = OTLookup(d.value.id);
- assert(p != NULL);
- if (p->tag == P_OBLIT) {
- if (!bflag) ensureGenerate(getCodeOID(p));
- if (p->b.oblit.f.immutable) {
- saveRelocationInfo(currentInstruction, 2, AR_OIDToODAP, d.value.id,
- getCodeOID(p));
- } else if (Zflag) {
- saveRelocationInfo(currentInstruction, 2, AR_OIDToCheatingODP, d.value.id,
- getCodeOID(p));
- } else {
- saveRelocationInfo(currentInstruction, 2, AR_OIDToODP, d.value.id,
- getCodeOID(p));
- }
- } else {
- assert(p->tag == P_ATLIT);
- saveRelocationInfo(currentInstruction, 2, AR_OIDToODP, d.value.id,
- OIDOfBuiltin(B_INSTCT, SIGNATUREINDEX));
- }
- break;
- case DD_OIDToODAP:
- emit("%c0xabcdef01", IMMEDIATECHAR);
- saveRelocationInfo(currentInstruction, 2, AR_OIDToODAP, d.value.id, 0);
- break;
- case DD_OIDToCodePtr:
- emit("%c0xabcdef01", IMMEDIATECHAR);
- saveRelocationInfo(currentInstruction, 2, AR_OIDToCodePtr, d.value.id, 0);
- break;
- case DD_AbCon:
- emit("%c0xabcdef01", IMMEDIATECHAR);
- ensureGenerate(getDDAbstractType(d));
- if (!bflag) ensureGenerate(getDDConcreteType(d));
- saveRelocationInfo(currentInstruction, 2, AR_OIDOIDToAbCon,
- getDDAbstractType(d), getDDConcreteType(d));
- break;
- default:
- assert(FALSE);
- break;
- }
- if (c != '\0') (void) emit("%c", c);
- }
-
- void debugDD(d)
- DD d;
- {
- displayDD(stdout, d, '\n');
- fflush(stdout);
- }
-
- void displayDD(f, d, c)
- FILE *f;
- DD d;
- char c;
- {
- switch (d.kind) {
- case DD_Label:
- #ifdef sun
- emit("pc@(");
- #endif
- if (d.value.label < 100) {
- fprintf(f, "%d%c", abs(d.value.label),
- d.value.label < 0 ? 'b' : 'f');
- } else {
- fprintf(f, "L_%d", d.value.label);
- }
- #ifdef sun
- emit("-.-2)");
- #endif
- break;
- case DD_Address:
- fprintf(f, addressToString(d.value.address));
- if (d.value.address.baseIsTemporary) {
- if (d.value.address.base == Register) {
- fprintf(f, " (t%s)", RN(d.value.address.offset));
- } else if (d.value.address.base == regs_l) {
- /* this really means free the temp stack storage */
- fprintf(f, " (ts%d)", d.value.address.offset);
- } else {
- fprintf(f, " (t%s)", RN(d.value.address.base));
- }
- }
- if (d.value.address.indexIsTemporary) {
- fprintf(f, " (ti %s)", RN(d.value.address.indexReg));
- }
- break;
- case DD_Manifest:
- if (d.value.manifest & 0xc0000000) {
- fprintf(f, "%c0x%08x", IMMEDIATECHAR, d.value.manifest);
- } else {
- fprintf(f, "%c%d", IMMEDIATECHAR, d.value.manifest);
- }
- break;
- case DD_RealManifest:
- #ifdef vax
- fprintf(f, "%c0f%s", IMMEDIATECHAR, d.value.realmanifest);
- #endif
- #ifdef sun
- if (formatAs0r) {
- fprintf(f, "%c0r%s", IMMEDIATECHAR, d.value.realmanifest);
- } else {
- float fl;
- double atof();
- fl = atof(d.value.realmanifest);
- fprintf(f, "%c0x%08x", IMMEDIATECHAR, (* ((int *)&fl)));
- }
- #endif
- break;
- case DD_PSLCondition:
- fprintf(f, "psl %s", JN(d.value.condition.psl));
- break;
- case DD_OIDToODP:
- fprintf(f, "OIDToODP 0x%08x", d.value.id);
- break;
- case DD_OIDToODAP:
- fprintf(f, "OIDToODAP 0x%08x", d.value.id);
- break;
- case DD_OIDToCodePtr:
- fprintf(f, "OIDToCodePtr 0x%08x", d.value.id);
- break;
- case DD_AbCon:
- fprintf(f, "DD_AbCon 0x%08x 0x%08x",
- getDDAbstractType(d), getDDConcreteType(d));
- break;
- default:
- fprintf(f, "JUNK!");
- break;
- }
- if (c == '\n' && d.kind != DD_AbCon) {
- fprintf(f, " AT = 0x%08x\n", getDDAbstractType(d));
- } else if (c != '\0') (void) fputc(c, f);
- }
-
- void generateKernelCall(opName)
- char *opName;
- {
- Boolean checkJump;
- if (!strcmp(opName, "em_stackCheck") ||
- !strcmp(opName, "ems_compare") ||
- !strcmp(opName, "emtime_compare") ||
- !strcmp(opName, "em_invokeAssumptionFailure")) checkJump = FALSE;
- else checkJump = TRUE;
- if (checkJump) JUMPDEBUG();
- emit("\tj%s\t%s_%s\n", JN(SUBR), GLOBALVARINDICATOR, opName);
- if (checkJump) JUMPCHECK();
- }
-
- void writeData(n)
- int n;
- {
- emit("\t.long\t%d\n", n);
- }
-
- void writeWord(n)
- int n;
- {
- emit("\t.word\t%d\n", n);
- }
-
- void writeHex(n)
- OID n;
- {
- emit("\t.long\t0x%.8x\n", n);
- }
-
- void writeHexComment(n, c)
- OID n;
- char *c;
- {
- emit("\t.long\t0x%.8x", n);
- Comment(c);
- }
-
- static ODTag nullTag;
-
- ODTag BuildTag(fBasicTag, fReplicated)
- ODBasicTag fBasicTag;
- Boolean fReplicated;
- {
- register ODTag t;
- t = nullTag;
- t.otherstuff = OBSCUREVALUE;
- t.tag = fBasicTag;
- t.replicated = fReplicated;
- if (t.tag == GODataTag && fReplicated) {
- /* We introduced LOTag to handle local objects, and at the moment,
- * replicated objects are local.
- */
- t.tag = LOTag;
- }
- return(t);
- }
-
- /*
- * The IP to Template map is generated on the basis of well known names.
- * All we need is the number of routines, and whether the initially,
- * process, and recovery sections exist.
- */
-
- /*
- * The IPToLineNumber, IP to UnavailableHandler, and IP to FailureHandler
- * maps are saved as code is generated. The failure and unavailable handler
- * maps require a stack as they nest. The line number map is simple.
- */
- #define NEWIPMAPCOLLECTOR(N) ((IPMapCollectorPtr) malloc(sizeof(IPMapCollector) +\
- ((N)-1)*3*sizeof(int)))
-
- IPMapCollectorPtr createIPMap(lowCodeLabel)
- int lowCodeLabel;
- {
- register IPMapCollectorPtr p;
- p = NEWIPMAPCOLLECTOR(10);
- p->maxSize = 10;
- p->nextToFill = 0;
- p->lowCodeLabel = lowCodeLabel;
- return(p);
- }
-
- void addToIPMap(p, codeLabel, dataLabel, value)
- IPMapCollectorPtr *p;
- int codeLabel, dataLabel, value;
- {
- register IPMapCollectorPtr lp = *p;
- register int index;
- register IPMapCEntryPtr ipme;
-
- if (doGenerateCode) return;
- if (lp->nextToFill == 0) {
- if (dataLabel < 0 && value == 0) {
- /* this is a non-existant first entry */
- lp->lowCodeLabel = codeLabel;
- return;
- }
- } else {
- ipme = &lp->entry[lp->nextToFill - 1];
- if (ipme->dataLabel < 0 && dataLabel < 0) {
- if (ipme->value == value) {
- ipme->codeLabel = codeLabel;
- return;
- }
- } else if (ipme->dataLabel == dataLabel) {
- ipme->codeLabel = codeLabel;
- return;
- }
- }
- if (lp->nextToFill >= lp->maxSize) {
- IPMapCollectorPtr np;
- register int i;
- np = NEWIPMAPCOLLECTOR((unsigned)2 * lp->maxSize);
- np->maxSize = 2 * lp->maxSize;
- np->nextToFill = lp->nextToFill;
- np->lowCodeLabel = lp->lowCodeLabel;
- for (i = 0; i < lp->maxSize; i++) {
- np->entry[i] = lp->entry[i];
- }
- free((char *)lp);
- *p = np;
- lp = np;
- }
- index = lp->nextToFill;
- lp->entry[index].codeLabel = codeLabel;
- lp->entry[index].dataLabel = dataLabel;
- lp->entry[index].value = value;
- lp->nextToFill++;
- }
-
- void dumpIPMap(p)
- register IPMapCollectorPtr p;
- {
- register int i;
- i = p->nextToFill - 1;
- if (i >= 0 && p->entry[i].dataLabel < 0 && p->entry[i].value == 0) {
- i--;
- p->nextToFill --;
- }
- if (p->nextToFill > 0) {
- emit("\t.long\tL_%d - L_beginCDA\n",
- i >= 0 ? p->entry[i].codeLabel : p->lowCodeLabel);
- emit("\t.long\tL_%d - L_beginCDA\n", p->lowCodeLabel);
- for (i = 0; i < p->nextToFill; i++) {
- emit("\t.long\tL_%d - L_beginCDA\n", p->entry[i].codeLabel);
- if (p->entry[i].dataLabel >= 0) {
- emit("\t.long\tL_%d - L_beginCDA\n", p->entry[i].dataLabel);
- } else {
- writeData(p->entry[i].value);
- }
- }
- }
- if (doGenerateCode) free((char *) p);
- }
-
- /*
- * The op vector is also done on the basis of well known names.
- */
-
- /*
- * Utility routines for saving relocation information and eventual writing to
- * the code file.
- */
- static RelocationInfoPtr relocPtr;
- static unsigned int relocationSize;
-
- void initializeRelocationInfo()
- {
- # define MINIMUMSIZE 50
- relocPtr = NEWRelocationInfo(MINIMUMSIZE);
- relocPtr->numEntries = 0;
- relocationSize = MINIMUMSIZE;
- # undef MINIMUMSIZE
- }
-
- void saveRelocationInfo(labelNumber, offset, kind, OID1, OID2)
- int labelNumber, offset;
- AR_Kind kind;
- OID OID1, OID2;
- {
- register RelocationInfoPtr np;
- register int i;
- if (relocPtr->numEntries >= relocationSize) {
- relocationSize *= 2;
- np = NEWRelocationInfo(relocationSize);
- np->numEntries = relocPtr->numEntries;
- for (i = 0; i < relocPtr->numEntries; i++) {
- np->relocation[i] = relocPtr->relocation[i];
- }
- free((char *) relocPtr);
- relocPtr = np;
- }
- i = relocPtr->numEntries++;
- relocPtr->relocation[i].kind = kind;
- relocPtr->relocation[i].where = (labelNumber << 8) + offset;
- relocPtr->relocation[i].theOID1 = OID1;
- relocPtr->relocation[i].theOID2 = OID2;
- }
-
- void dumpRelocationInfo()
- {
- register int i;
- register ARelocationPtr ar;
- register int label, offset;
-
- emit("L_relocInfoStart:\n");
- writeData(relocPtr->numEntries);
- for (i = 0; i < relocPtr->numEntries; i++) {
- ar = &relocPtr->relocation[i];
- label = (ar->where >> 8) & 0xffff;
- offset = (ar->where) & 0xff;
- #ifdef vax
- emit("\t.long\t((L_%d-L_beginCDA+%d)<<8)+%d\n",
- label, offset, (int) ar->kind);
- #else
- #ifdef sun
- emit("\t.long\t(L_%d-L_beginCDA+%d)+((%d)*%d)\n",
- label, offset, (int) ar->kind, 1<<24);
- #endif
- #endif
- writeHex(ar->theOID1);
- writeHex(ar->theOID2);
- }
- free((char *) relocPtr);
- relocPtr = NULL;
- }
-
- /*
- * Utility routines for saving templates for eventual output to the code file.
- */
-
- typedef struct sTemplateDescription {
- char *name;
- int number;
- TemplatePtr tp;
- } TemplateDescription, *TemplateDescriptionPtr;
-
- typedef struct sTDC {
- int numEntries;
- TemplateDescription td[12];
- } TDC, *TDCPtr;
- #define NEWTDC(N) ((TDCPtr) malloc(\
- (unsigned) (sizeof(TDC) -\
- 12 * sizeof(TemplateDescription) +\
- (N) * sizeof(TemplateDescription))))
-
- static TDCPtr tdcPtr;
- static int TDCSize;
-
- static TemplatePtr tempPtr;
- static unsigned int templateSize;
-
- void initializeTemplates()
- {
- # define MINIMUMSIZE 50
- tdcPtr = NEWTDC(MINIMUMSIZE);
- TDCSize = MINIMUMSIZE;
- tdcPtr->numEntries = 0;
- # undef MINIMUMSIZE
- }
-
- extern char *strdup();
-
- void setHasInvokeQueueBit(hasInvokeQueue)
- Boolean hasInvokeQueue;
- {
- tdcPtr->td[tdcPtr->numEntries-1].tp->B.hasInvokeQueue = hasInvokeQueue;
- }
-
- void initializeTemplate(name, number, exclusiveAccess)
- char *name;
- int number;
- Boolean exclusiveAccess;
- {
- register TDCPtr np;
- register int i;
- name = strdup(name);
- if (tdcPtr->numEntries >= TDCSize) {
- TDCSize *= 2;
- np = NEWTDC(TDCSize);
- np->numEntries = tdcPtr->numEntries;
- for (i = 0; i < tdcPtr->numEntries; i++) {
- np->td[i] = tdcPtr->td[i];
- }
- free((char *) tdcPtr);
- tdcPtr = np;
- }
- # define MINIMUMSIZE 50
- tempPtr = NEWTemplate(MINIMUMSIZE);
- tempPtr->B.numEntries = 0;
- templateSize = MINIMUMSIZE;
- tdcPtr->td[tdcPtr->numEntries].name = name;
- tdcPtr->td[tdcPtr->numEntries].number = number;
- tdcPtr->td[tdcPtr->numEntries].tp = tempPtr;
-
- tempPtr->B.exclusiveAccess = exclusiveAccess;
- tempPtr->B.hasInvokeQueue = FALSE;
- tempPtr->B.notUsed = 0;
- tdcPtr->numEntries++;
- # undef MINIMUMSIZE
- }
-
- static void checkForRoomInTemplate()
- {
- register TemplatePtr np;
- register int i;
- if (tempPtr->B.numEntries >= templateSize) {
- templateSize *= 2;
- np = NEWTemplate(templateSize);
- np->B.numEntries = tempPtr->B.numEntries;
- for (i = 0; i < tempPtr->B.numEntries; i++) {
- np->entry[i] = tempPtr->entry[i];
- }
- free((char *) tempPtr);
- tempPtr = np;
- tdcPtr->td[tdcPtr->numEntries-1].tp = tempPtr;
- }
- }
-
- void saveShortStaticTemplate(theBrand, paramInfo, elementBrand, count,
- attachedFlag)
- Brand theBrand, elementBrand;
- ParamInfo paramInfo;
- int count;
- Boolean attachedFlag;
- {
- register ShortStatic t, ot;
- checkForRoomInTemplate();
- if (tempPtr->B.numEntries > (unsigned)0) {
- ot = tempPtr->entry[tempPtr->B.numEntries-1].TE.SS;
- if (ot.Format == ShortStaticF &&
- ot.theBrand == theBrand &&
- ot.paramInfo == paramInfo &&
- ot.elementBrand == elementBrand &&
- ot.attachedFlag == attachedFlag) {
- ot.count += count;
- tempPtr->entry[tempPtr->B.numEntries-1].TE.SS = ot;
- return;
- }
- }
- t.Format = ShortStaticF;
- t.theBrand = theBrand;
- t.paramInfo = paramInfo;
- t.attachedFlag = attachedFlag;
- t.elementBrand = elementBrand;
- t.count = count;
- tempPtr->entry[tempPtr->B.numEntries].TE.SS = t;
- tempPtr->B.numEntries++;
- }
-
- void saveRegisterTemplate(theBrand, storedWhere, reg, count, attachedFlag)
- Brand theBrand;
- Placement storedWhere;
- int reg, count;
- Boolean attachedFlag;
- {
- register RegisterTE t;
- register RegisterTE ot;
- checkForRoomInTemplate();
- if (tempPtr->B.numEntries > (unsigned)0) {
- ot = tempPtr->entry[tempPtr->B.numEntries-1].TE.R;
- if (ot.Format == RegisterF &&
- ot.theBrand == theBrand &&
- ot.storedWhere == storedWhere &&
- ot.attachedFlag == attachedFlag) {
- ot.count += count;
- tempPtr->entry[tempPtr->B.numEntries-1].TE.R = ot;
- return;
- }
- }
- t.Format = RegisterF;
- t.theBrand = theBrand;
- t.storedWhere = storedWhere;
- t.attachedFlag = attachedFlag;
- t.unusedFlag = FALSE;
- t.reg = reg;
- t.count = count;
- tempPtr->entry[tempPtr->B.numEntries].TE.R = t;
- tempPtr->B.numEntries++;
- }
-
- extern char *brandNames[];
- char *ParamInfoNames[] = {
- "",
- "arg",
- "res",
- "moveres"
- };
-
- void commentTemplate(t)
- register TemplateEntryPtr t;
- {
- if (!doGenerateCode) return;
- fprintf(codeFile, " %c ", COMMENTCHAR);
-
-
- switch (t->TE.SS.Format) {
- case ShortStaticF:
- fprintf(codeFile,
- "%3d %s%s %s",
- t->TE.SS.count,
- t->TE.SS.attachedFlag ? "attached " : "",
- ParamInfoNames[(int)t->TE.SS.paramInfo],
- brandNames[(int)t->TE.SS.theBrand]);
- if (t->TE.SS.theBrand == VectorBrand)
- fprintf(codeFile, " of %s",
- brandNames[(int)t->TE.SS.elementBrand]);
- break;
- case RegisterF:
- fprintf(codeFile, "%sregister %s",
- t->TE.R.attachedFlag ? "attached " : "",
- registerName[t->TE.R.reg]);
- if (t->TE.R.count > 1)
- fprintf(codeFile, " - %s", registerName[t->TE.R.reg+t->TE.R.count-1]);
- fprintf(codeFile, " %s%s",
- brandNames[(int)t->TE.R.theBrand],
- t->TE.R.storedWhere == InRegister ? "" : " insavearea");
- break;
- default:
- break;
- }
- (void) fputc('\n', codeFile);
- }
-
- void dumpTemplate(name, number, tp)
- char *name;
- int number;
- TemplatePtr tp;
- {
- register int i;
- register TemplateEntryPtr te;
-
- emit(name, number);
- emit(":\n");
- writeTag(tp->B);
-
- for (i = 0; i < tp->B.numEntries; i++) {
- te = &tp->entry[i];
- switch (te->TE.SS.Format) {
- case ShortStaticF:
- writeTag(te->TE.SS);
- break;
- case RegisterF:
- writeTag(te->TE.R);
- break;
- default:
- assert(FALSE);
- break;
- }
- commentTemplate(te);
- }
- free((char *) tp);
- }
-
- void dumpTemplates()
- {
- register int i;
- register TemplateDescriptionPtr td;
-
- for (i = 0; i < tdcPtr->numEntries; i++) {
- td = &tdcPtr->td[i];
- dumpTemplate(td->name, td->number, td->tp);
- }
- free((char *) tdcPtr);
- }
-
- int findATOpNumber(at, opName)
- NodePtr at, opName;
- {
- register NodePtr sigs, asig, aname;
- register OID theID;
-
- assert(at->tag == P_ATLIT);
- assert(opName->tag == P_OPNAME);
- theID = opName->b.opname.id;
- sigs = at->b.atlit.ops;
- assert(isASequence(sigs));
- Sequence_For(asig, sigs)
- assert(asig->tag == P_OPSIG);
- aname = asig->b.opsig.name;
- assert(aname->tag == P_OPNAME);
- if (aname->b.opname.id == theID) return(z__z);
- Sequence_Next
- assert(FALSE);
- /*NOTREACHED*/
- }
-
- NodePtr resolveOIDToCTOrAT(id)
- OID id;
- {
- register NodePtr p, q = NULL;
- register OID codeoid;
-
- p = OTLookup(id);
- assert((int)p != NIL);
- if (p->tag == P_ATLIT) {
- if (p->b.atlit.f.cannotBeConformedTo) {
- codeoid = getCodeOID(p);
- assert(codeoid != 0);
- q = OTLookup(codeoid);
- assert(q->tag == P_OBLIT);
- assert(q != NULL);
- p = q;
- }
- }
- return(p);
- }
-
- NodePtr resolveToCTOrAT(p)
- NodePtr p;
- {
- Symbol st;
- OID id;
- NodePtr q;
- switch (p->tag) {
- case P_GLOBALREF:
- resolveGlobal(p, (ValuePtr) NULL);
- return(resolveToCTOrAT(p->b.globalref.value));
- /* break; */
- case P_OBLIT:
- return(p);
- /* break; */
- case P_ATLIT:
- id = getCodeOID(p);
- if (id != 0) {
- q = OTLookup(id);
- assert((int)q != NIL);
- return(q);
- } else if (p->b.atlit.f.writeSeparately) {
- assert(p->b.atlit.id != 0);
- return(resolveOIDToCTOrAT(p->b.atlit.id));
- } else {
- return(p);
- }
- /* break; */
- case P_SYMREF:
- st = ST_Fetch(p->b.symref.symbol);
- assert(st->isManifest);
- assert(st->value.value != NULL);
- return(resolveToCTOrAT(st->value.value));
- /* break; */
- default:
- assert(FALSE);
- /*NOTREACHED*/
- /* break; */
- }
- }
-
- /*
- * Return the best description of the entity that will result by executing
- * the expression.
- */
- NodePtr getBestInfoFromExpression(p)
- register NodePtr p;
- {
- Symbol st;
- assert ((int)p > 0x200);
- switch (p->tag) {
- case P_BUILTINLIT:
- return(refToBuiltinFromToken(B_IT, p->b.builtinlit.whichType));
- /* break; */
- case P_INTLIT:
- return(refToBuiltin(B_INSTCT, INTEGERINDEX));
- /* break; */
- case P_BOOLLIT:
- return(refToBuiltin(B_INSTCT, BOOLEANINDEX));
- /* break; */
- case P_STRINGLIT:
- return(refToBuiltin(B_INSTCT, STRINGINDEX));
- /* break; */
- case P_INVOC:
- return(resolveOIDToCTOrAT(p->b.invoc.resultTypeOID));
- /* break; */
- case P_ATLIT:
- return(refToBuiltin(B_INSTCT, SIGNATUREINDEX));
- /* break; */
- case P_GLOBALREF:
- resolveGlobal(p, (ValuePtr) NULL);
- return(getBestInfoFromExpression(p->b.globalref.value));
- /* break; */
- case P_OBLIT:
- return(p);
- /* break; */
- case P_SYMREF:
- st = ST_Fetch(p->b.symref.symbol);
- if (st->value.CTinfo != NULL)
- return(resolveToCTOrAT(st->value.CTinfo));
- else
- return(resolveToCTOrAT(st->value.ATinfo));
- /* break; */
- default:
- assert(FALSE);
- /*NOTREACHED*/
- /* break; */
- }
- }
-
- OID getCodeID(p)
- NodePtr p;
- {
- NodePtr q;
- p = GETVALUE(p);
- if (p->tag == P_OBLIT) {
- return(getCodeOID(p));
- } else if (p->tag == P_BUILTINLIT) {
- q = refToBuiltinFromToken(B_INSTAT, p->b.builtinlit.whichType);
- q = resolveOIDToCTOrAT(q->b.atlit.id);
- assert(q->tag == P_OBLIT);
- return(getCodeOID(q));
- } else if (p->tag == P_ATLIT) {
- q = resolveOIDToCTOrAT(p->b.atlit.id);
- assert(q->tag == P_OBLIT);
- return(getCodeOID(q));
- } else {
- assert(FALSE);
- /*NOTREACHED*/
- }
- }
-
-
- OID getID(p)
- NodePtr p;
- {
- return(GETVALUE(p)->b.oblit.id);
- }
-
- NodePtr getValue(p)
- NodePtr p;
- {
- if (p->tag == P_GLOBALREF) {
- resolveGlobal(p, (ValuePtr) NULL);
- p = p->b.globalref.value;
- }
- assert(p->tag == P_ATLIT || p->tag == P_OBLIT);
- return(p);
- }
-
- DD buildAbCon(ATID, CTID)
- OID ATID, CTID;
- {
- DD result;
- result.kind = DD_AbCon;
- setDDConcreteType(result, CTID);
- setDDAbstractType(result, ATID);
- return(result);
- }
-
- DD buildAbConFromObject(p)
- NodePtr p;
- {
- NodePtr q;
- q = GETVALUE(p->b.oblit.myat);
- assert(q->tag == P_ATLIT);
- return(buildAbCon(q->b.atlit.id, getCodeOID(p)));
- }
-
- DD buildRegisterDD(registerNumber)
- int registerNumber;
- {
- DD d;
- d = nullDD;
- d.kind = DD_Address;
- d.value.address = nullAddress;
- d.value.address.base = Register;
- d.value.address.offset = registerNumber;
- if (registerNumber < 0) {
- implementationBug("Out of temporary registers");
- } else if (registerNumber < 4) {
- d.value.address.baseIsTemporary = TRUE;
- ensureAllocated(registerNumber, 1);
- }
- return(d);
- }
-
- DD buildRegisterDDNC(registerNumber)
- int registerNumber;
- {
- DD d;
- d = nullDD;
- d.kind = DD_Address;
- d.value.address = nullAddress;
- d.value.address.base = Register;
- d.value.address.offset = registerNumber;
- setDDAbstractType(d, OIDOfBuiltin(B_INSTAT, INTEGERINDEX));
- return(d);
- }
-
- DD buildAddressDD(regNo, offset)
- int regNo, offset;
- {
- DD d;
- d = nullDD;
- d.kind = DD_Address;
- d.value.address.base = regNo;
- d.value.address.offset = offset;
- setDDAbstractType(d, OIDOfBuiltin(B_INSTAT, INTEGERINDEX));
- return(d);
- }
-
- DD buildLabelDD(labelNumber)
- int labelNumber;
- {
- DD d;
- d = nullDD;
- d.kind = DD_Label;
- d.value.label = labelNumber;
- return(d);
- }
-
- DD buildManifestDD(value)
- int value;
- {
- DD d;
- d = nullDD;
- d.kind = DD_Manifest;
- d.value.manifest = value;
- return(d);
- }
-
- DD buildConCon(index)
- int index;
- {
- NodePtr theAbObject;
- theAbObject = refToBuiltin(B_INSTAT, index);
- assert(theAbObject->tag == P_ATLIT);
- if (theAbObject->b.atlit.f.cannotBeConformedTo) {
- return(buildAbCon(OIDOfBuiltin(B_INSTAT, index),
- OIDOfBuiltin(B_INSTCT, index)));
- } else {
- return(buildAbCon(OIDOfBuiltin(B_INSTCT, index),
- OIDOfBuiltin(B_INSTCT, index)));
- }
- }
-
- DD increaseIndirection(d)
- DD d;
- {
- assert(d.kind == DD_Address);
- assert(d.value.address.base == Register);
- d.value.address.base = d.value.address.offset;
- d.value.address.offset = 0;
- return(d);
- }
-
- void freeDD(d)
- DD d;
- {
- if (d.kind == DD_Address) {
- if (d.value.address.baseIsTemporary) {
- if (d.value.address.base == Register) {
- freeReg((unsigned)d.value.address.offset, 1);
- } else if (d.value.address.base == regs_l) {
- /* this really means free the temp stack storage */
- TS_Free(d.value.address.offset);
- } else {
- freeReg(d.value.address.base, 1);
- }
- }
- if (d.value.address.indexIsTemporary) {
- freeReg(d.value.address.indexReg, 1);
- }
- }
- }
-
- #ifdef TRASHOPNUMBERS
- int translateATOpNumberToCTOpNumber(dd, abstractOpNumber)
- DD dd;
- int abstractOpNumber;
- {
- OID atOID, ctOID, opOID;
- NodePtr at, ct;
- register NodePtr p, ops;
- int stage, concreteOpNumber;
- Boolean found = FALSE;
-
- assert(dd.kind == DD_AbCon);
- atOID = getDDAbstractType(dd);
- ctOID = getDDConcreteType(dd);
- at = resolveOIDToCTOrAT(atOID);
- ct = resolveOIDToCTOrAT(ctOID);
- TRACE0(atctsort, 5, "translate at to ct op number:");
- TRACE3(atctsort, 5, "at = %s ct = %s number = %d", ATName(at), ATName(ct),
- abstractOpNumber);
- if (at->tag == P_OBLIT) {
- /*
- * We know the concrete type given the abstract type, so we have the
- * right operation number already.
- */
- TRACE0(atctsort, 7, "Know ct");
- concreteOpNumber = abstractOpNumber;
- } else {
- assert(at->tag == P_ATLIT);
- assert(ct->tag == P_OBLIT);
- p = at->b.atlit.ops;
- assert(isASequence(p));
- assert(abstractOpNumber >= 0 && abstractOpNumber < Sequence_Length(p));
- p = p->b.children[abstractOpNumber];
- assert(p->tag == P_OPSIG);
- TRACE1(atctsort, 7, "Operation name = %s", SigName(p));
- p = p->b.opsig.name;
- assert(p->tag == P_OPNAME);
- opOID = p->b.opname.id;
- for (stage = 0; stage < 2 && !found; stage++) {
- if (stage == 0) {
- ops = ct->b.oblit.monitor;
- if (ops != NULL) {
- assert(ops->tag == P_MONITOR);
- ops = ops->b.monitor.ops;
- }
- } else if (stage == 1) {
- ops = ct->b.oblit.ops;
- }
- Sequence_For(p, ops)
- assert(p->tag == P_OPDEF);
- concreteOpNumber = p->b.opdef.opNumber;
- p = p->b.opdef.sig;
- assert(p->tag == P_OPSIG);
- p = p->b.opsig.name;
- assert(p->tag == P_OPNAME);
- if (opOID == p->b.opname.id) {
- found = TRUE;
- break;
- }
- Sequence_Next
- }
- assert(found);
- }
- TRACE1(atctsort, 5, "returning %d", concreteOpNumber);
- return(concreteOpNumber);
- }
- #endif
-
- NodePtr getCTInfo(st)
- register Symbol st;
- {
- register NodePtr ct;
- if (st->value.CTinfo != NULL) {
- ct = st->value.CTinfo;
- } else {
- ct = resolveToCTOrAT(st->value.ATinfo);
- if (ct->tag != P_OBLIT) {
- ct = NULL;
- } else {
- st->value.CTinfo = ct;
- }
- }
- if (ct != NULL) ct = GETVALUE(ct);
- return(ct);
- }
-
- NodePtr getBestInfoFromAbCon(d)
- DD d;
- {
- OID ctoid;
- NodePtr ct;
- if (d.kind == DD_AbCon) {
- ctoid = getDDConcreteType(d);
- ct = OTLookup(ctoid);
- assert(ct != NN);
- assert(ct->tag == P_OBLIT);
- } else {
- ctoid = getDDAbstractType(d);
- ct = resolveOIDToCTOrAT(ctoid);
- assert(ct->tag == P_ATLIT || ct->tag == P_OBLIT);
- }
- return(ct);
- }
-
- NodePtr ATCTOIDToCTPtr(atoid, ctoid)
- OID atoid, ctoid;
- {
- NodePtr ct;
- if (ctoid != 0) {
- ct = resolveOIDToCTOrAT(ctoid);
- } else {
- ct = resolveOIDToCTOrAT(atoid);
- }
- return(ct);
- }
-
- NodePtr getConcreteTypeFromAbCon(d)
- DD d;
- {
- OID ctoid;
- NodePtr ct;
- assert(d.kind == DD_AbCon);
- ctoid = getDDConcreteType(d);
- ct = OTLookup(ctoid);
- assert(ct != NN);
- return(ct);
- }
-
- /*
- * This one returns the symbol of the result of getelement on the
- * given object constructor.
- */
- Symbol getElementTypeSymbol(ct)
- NodePtr ct;
- {
- register NodePtr p;
- Symbol elementTypeSymbol;
- char *getelementname = "getelement";
-
- assert(ct->tag == P_OBLIT);
- p = Construct(P_OPNAME, 0);
- p->b.opname.ident = Ident_Lookup(getelementname, strlen(getelementname));
- p->b.opname.id = ON_Translate(getelementname);
- p = findObjectOperation(ct, p);
- assert(p->tag == P_OPDEF);
- p = p->b.opdef.sig;
- assert(p->tag == P_OPSIG);
- p = p->b.opsig.results->b.children[0]->b.param.sym;
- assert(p != NULL);
- assert(p->tag == P_SYMDEF);
- elementTypeSymbol = ST_Fetch(p->b.symdef.symbol);
- return(elementTypeSymbol);
- }
-
- int getSymbolSize(st)
- Symbol st;
- {
- int size = -1;
- AllocateKind ak;
-
- ATCTToSizeAndKind(st->value.ATinfo, st->value.CTinfo, st->isAttached,
- &size, &ak);
- assert(size != -1);
- return(size);
- }
-
- Brand oidToBrand(atoid)
- OID atoid;
- {
- switch (atoid) {
- case OIDOfBuiltin(B_INSTAT, BOOLEANINDEX):
- case OIDOfBuiltin(B_INSTAT, REALINDEX):
- case OIDOfBuiltin(B_INSTAT, CHARACTERINDEX):
- case OIDOfBuiltin(B_INSTAT, INTEGERINDEX):
- case OIDOfBuiltin(B_INSTCT, BOOLEANINDEX):
- case OIDOfBuiltin(B_INSTCT, REALINDEX):
- case OIDOfBuiltin(B_INSTCT, CHARACTERINDEX):
- case OIDOfBuiltin(B_INSTCT, INTEGERINDEX):
- return(DataBrand);
- default:
- return(ODPBrand);
- }
- }
-
- Brand abConToBrand(d)
- DD d;
- {
- OID atoid;
- atoid = getDDAbstractType(d);
- return(oidToBrand(atoid));
- }
-
- void HSPush(p, startlabel, fhlabel, belabel, loopexitlabel, parent)
- NodePtr p;
- int startlabel, fhlabel, belabel, loopexitlabel;
- BEntryPtr parent;
- {
- register HSEntryPtr np;
- TRACE4(handler, 1, "Push: start %d fh %d be %d parent %x", startlabel,
- fhlabel, belabel, parent);
- np = (HSEntryPtr) malloc(sizeof(HSEntry));
- np->p = p;
- np->startlabel = startlabel;
- np->fhlabel = fhlabel;
- np->belabel = belabel;
- np->loopexitlabel = loopexitlabel;
- np->parent = parent;
- np->next = HSStackTop;
- HSStackTop = np;
- }
-
- void HSDump()
- {
- HSEntryPtr p;
- NodePtr handler;
- Variable kernObject;
- Symbol st;
- int endlabel;
-
- while (HSStackTop != NULL) {
- p = HSStackTop;
- HSStackTop = HSStackTop->next;
- handler = p->p;
- TRACE4(handler, 1, "HSDump: start %d fh %d be %d parent %x", p->startlabel,
- p->fhlabel, p->belabel, p->parent);
- assert(loops == NULL);
- if (p->loopexitlabel != 0) {
- loops = (LoopRecordPtr) malloc(sizeof(LoopRecord));
- loops->label = p->loopexitlabel;
- loops->enclosing = NULL;
- }
- #ifdef vax
- emit("\t.byte\t0\n");
- #endif
- #ifdef sun
- emit("\t.word\t0\n");
- #endif
- endlabel = nextLabelNumber++;
- emit("L_%d:\n", p->startlabel);
- IFOPTION(comment, 1)
- Comment("\t\t\t\t%s handler start",
- handler->tag == P_UNAVAILABLEHANDLER ? "unavailable" : "failure");
- TS_fixSPForHandler();
- if (handler->tag == P_UNAVAILABLEHANDLER) {
- TRACE0(handler, 1, "unavailable handler");
- BStackTop = p->parent;
- TRACE1(handler, 1, "Popping stack to %x", BStackTop);
- if (handler->b.unavailablehandler.decl != NULL) {
- lineNumberComment(handler->b.unavailablehandler.decl);
- st = ST_Fetch(handler->b.unavailablehandler.decl->b.vardecl.sym->b.symdef.symbol);
- /* TODO: the run-time type check */
- vPushVariable(st);
- claimReg(regs_arg1, 2, VariableBrand);
- kernObject.data = buildRegisterDD(regs_arg1);
- kernObject.abCon = nextAddress(kernObject.data);
- vPush(kernObject);
- vGenerateAssign();
- }
- TRACE0(handler, 1, "generating handler");
- generate(handler->b.unavailablehandler.body);
- TRACE2(handler, 1, "add to failure code %d handler %d", endlabel,
- p->fhlabel);
- addToIPMap(&failureHandlerMap, endlabel, p->fhlabel, 0);
- TRACE0(handler, 1, "Setting unavailable of stack top to -1");
- BStackTop->uhlabel = -1;
- } else if (handler->tag == P_FAILUREHANDLER) {
- TRACE0(handler, 1, "failure handler");
- BStackTop = p->parent;
- TRACE1(handler, 1, "Popping stack to %x", BStackTop);
- BStackTop->fhlabel =
- BStackTop->parent == NULL ? -1 : BStackTop->parent->fhlabel;
- TRACE1(handler, 1, "Setting failure handler of stack top to %d",
- BStackTop->fhlabel);
- generate(handler->b.failurehandler.body);
- } else {
- assert(FALSE);
- }
- emit("\tj%s\tL_%d\n", JN(ALWAYS), p->belabel);
- emit("L_%d:\n", endlabel);
- free((char *) p);
- if (loops != NULL) {
- free((char *)loops);
- loops = NULL;
- }
- }
- }
-
- void blockStart(p)
- NodePtr p;
- {
- int bslabel, uhlabel, fhlabel, belabel;
- register BEntryPtr np;
-
- bslabel = nextLabelNumber++;
- belabel = nextLabelNumber++;
-
- TRACE2(handler, 1, "Block start bs = %d be = %d", bslabel, belabel);
- np = (BEntryPtr) malloc(sizeof(BEntry));
- if (p->b.block.failurehandler != NN) {
- fhlabel = nextLabelNumber++;
- TRACE0(handler, 1, "block has failure handler push");
- HSPush(p->b.block.failurehandler, fhlabel, -1, belabel,
- loops == NULL ? 0 : loops->label, np);
- } else if (BStackTop != NULL) {
- /*
- * we propogate the failure statically to the failure handler of
- * the containing block.
- */
- TRACE1(handler, 1, "block has no failure handler propogate to %d",
- BStackTop->fhlabel);
- fhlabel = BStackTop->fhlabel;
- } else {
- TRACE0(handler, 1, "block has no failure handler, no propogate possible");
- fhlabel = -1;
- }
- if (p->b.block.unavailablehandler != NN) {
- uhlabel = nextLabelNumber++;
- TRACE0(handler, 1, "Block has unavailable handler push");
- HSPush(p->b.block.unavailablehandler, uhlabel, fhlabel, belabel,
- loops == NULL ? 0 : loops->label, np);
- } else {
- TRACE0(handler, 1, "Block has no unavailable handler");
- uhlabel = -1;
- }
- emit("L_%d:\n", bslabel);
- if (BStackTop != NULL) {
- TRACE2(handler, 1, "add to unavailable code %d handler %d", bslabel,
- BStackTop->uhlabel);
- addToIPMap(&unavailableHandlerMap, bslabel, BStackTop->uhlabel, 0);
- TRACE2(handler, 1, "add to failure code %d handler %d", bslabel,
- BStackTop->fhlabel);
- addToIPMap(&failureHandlerMap, bslabel, BStackTop->fhlabel, 0);
- }
- np->bslabel = bslabel;
- np->uhlabel = uhlabel;
- np->fhlabel = fhlabel;
- np->belabel = belabel;
- np->parent = BStackTop;
- BStackTop = np;
- TRACE5(handler, 1, "Pushing %x on stack: bs %d uh %d fh %d be %d", BStackTop,
- bslabel, uhlabel, fhlabel, belabel);
- }
-
- void blockEnd()
- {
- BEntryPtr p = BStackTop;
- BStackTop = p->parent;
-
- TRACE1(handler, 1, "Popping stack to %x", BStackTop);
- TRACE4(handler, 1, "block end: bs = %d uh = %d fh = %d be = %d",
- p->bslabel, p->uhlabel, p->fhlabel, p->belabel);
- emit("L_%d:\n", p->belabel);
- TRACE2(handler, 1, "add to unavailable code %d handler %d", p->belabel, p->uhlabel);
- addToIPMap(&unavailableHandlerMap, p->belabel, p->uhlabel, 0);
- TRACE2(handler, 1, "add to failure code %d handler %d", p->belabel, p->fhlabel);
- addToIPMap(&failureHandlerMap, p->belabel, p->fhlabel, 0);
- }
-
- void emitBranchOnBit(bitNumber, clearOrSet, regNo, label)
- int bitNumber;
- char clearOrSet;
- int regNo;
- DD label;
- {
- #ifdef vax
- if (bitNumber == 0) {
- emit("\tblb%c\t(%s),", clearOrSet, RN(regNo));
- } else {
- emit("\tbb%c\t%c%d,(%s),", clearOrSet, IMMEDIATECHAR, bitNumber, RN(regNo));
- }
- writeLabel(label, '\n');
- #endif
- #ifdef sun
- int bitTstNumber, byteNumber;
- PSLCondition c;
- if (bitNumber == 0) {
- emit("\ttstl\t%s@\n", RN(regNo));
- c = (clearOrSet == 'c' ? PL : MI);
- } else {
- bitTstNumber = 7 - (bitNumber % 8);
- byteNumber = bitNumber / 8;
- if (byteNumber == 0) {
- emit("\tbtst\t%c%d,%s@\n", IMMEDIATECHAR, bitTstNumber, RN(regNo));
- } else {
- emit("\tbtst\t%c%d,%s@(%d)\n", IMMEDIATECHAR, bitTstNumber, RN(regNo),
- byteNumber);
- }
- c = (clearOrSet == 'c' ? EQL : NEQ);
- }
- emit("\tj%s\t", JN(c));
- writeLabel(label, '\n');
- #endif
- }
-